angular.module('musicApp', ['mobiscroll-listview', 'mobiscroll-form', 'mobiscroll-widget', 'mobiscroll-slider'])
.service('hash', ['$window', '$rootScope', function ($window, $rootScope) {
    // when the hash changes outside of digest loop, we need to call - ex. page reload with modal open -> back button will not trigger digest loop
    $window.addEventListener('hashchange', function () {
        $rootScope.$digest();
    });

    // returns the window location hash
    this.raw = function () { return window.location.hash; };

    // sets or updates a state in the hash
    this.pushState = function (obj) {
        var merged = angular.extend({}, this.getState(), obj);
        window.location.hash = '#' + serialize(merged);
    };

    // returns an object with the deserialized hash params
    this.getState = function () {
        var hash = this.raw();
        if (hash && hash[0] == '#')
            hash = hash.substring(1);
        return deserialize(hash);
    };

    // removes a state from the hash
    this.removeState = function (state) {
        var tempState = this.getState();
        tempState[state] = undefined;
        this.pushState(tempState);
    };

    function deserialize(str) {
        var regex = /(([\w]+)=([\w\-]*))/ig;
        var match, obj = {};
        while ((match = regex.exec(str)) !== null) {
            var key = match[2];
            var value = match[3];
            if (value !== undefined) {
                obj[key] = value;
            }
        }
        return obj;
    }
    function serialize(obj) {
        var str,
            first = true;

        for (var k in obj) {
            if (first) {
                str = k + '=' + obj[k];
                first = false;
            }
            else {
                str += '&' + k + '=' + obj[k];
            }
        }
        return str;
    }
}])
.controller('musicController', ['$scope', '$compile', '$timeout', 'hash', function ($scope, $compile, $timeout, hash) {
    var audio,
        currentIndex = 0,
        messageTimer,
        randomIndex = 0,
        message = $('#message');

    $scope.baseUrl = MS.domain || '';
    $scope.showHiddenPlayer = false;
    $scope.started = true;
    $scope.showPlayer = false;
    $scope.showPause = false;
    $scope.timeUpdate = true;
    $scope.theme = $.mobiscroll.settings.theme = MS.theme;
    $scope.repeat = false;
    $scope.shuffle = false;
    $scope.like = false;
    $scope.music = [{
        artist: 'Alexander Chereshnev',
        img: 'images/Alexander_2x.png',
        track: "Boutros Boutros Ghali",
        audio: 'sounds/Alexander_Chereshnev_-_Boutros_Boutros_Ghali.mp3',
        length: "5:31",
        startTime: '0',
        currTime: '0:00'
    }, {
        artist: 'Beat Doctor',
        img: 'images/Beatdoctor_2x.png',
        track: "The Piano Tune",
        audio: 'sounds/Beat_Doctor_-_10_-_The_Piano_Tune.mp3',
        length: "5:06",
        currTime: '0:00',
        startTime: '331',
        like: true
    }, {
        artist: 'Big Mean Sound Machive',
        img: 'images/BigMean_2x.png',
        track: "Burning Van",
        audio: 'sounds/Big_Mean_Sound_Machive_-_06_-_Burning_Van.mp3',
        length: "6:25",
        startTime: '637',
        currTime: '0:00',
        like: true
    }, {
        artist: 'Calling Sister Midnight',
        img: 'images/Calling_Sister_2x.png',
        track: "Make It Stop ft Mana Junkie",
        audio: 'sounds/Calling_Sister_Midnight_-_Make_It_Stop_ft_Mana_Junkie.mp3',
        length: "2:57",
        startTime: '1022',
        currTime: '0:00'
    }, {
        artist: 'Destinazione altrove',
        img: 'images/Destinazione_2x.png',
        track: "Vitamins (Remix)",
        audio: 'sounds/destinazione_altrove_-_Vitamins__Remix__ft_Clulow_Forester.mp3',
        length: "3:55",
        startTime: '1199',
        currTime: '0:00'
    }, {
        artist: 'Jeris',
        img: 'images/Jeris_2x.png',
        track: "Floating Through Time",
        audio: 'sounds/Jeris_-_Floating_Through_Time.mp3',
        length: "3:14",
        startTime: '1434',
        currTime: '0:00'
    }, {
        artist: 'Marylin-Rambo',
        img: 'images/Marlyn-Rambo_2x.png',
        track: "Igor ou Quoi",
        audio: 'sounds/Marylin-Rambo_-_07_-_Igor_ou_Quoi.mp3',
        length: "1:22",
        startTime: '1628',
        currTime: '0:00'
    }, {
        artist: 'Rey Izain',
        img: 'images/Rey_Izain_2x.png',
        track: "Dancing Like A Maniac",
        audio: 'sounds/Rey_Izain_-_Dancing_Like_A_Maniac_ft_The_Ragga_Twins_ft_Sybil_Smith_The_Ragga_Twins.mp3',
        length: "3:58",
        startTime: '1710',
        currTime: '0:00',

    }, {
        artist: 'Texasradiofish',
        img: 'images/2.jpg',
        track: "Just For You",
        audio: 'sounds/texasradiofish_-_Just_For_You_ft_Adam_Taha_ElRon_XChile_Revlin_grapes_Nickleus_Lucas_Gonze.mp3',
        length: "2:37",
        startTime: '1948',
        currTime: '0:00'
    }, {
        artist: 'Snowflake',
        img: 'images/Snowflake_2x.png',
        track: "Lost (Vivid Sound Lab Remix)",
        audio: 'sounds/vivid_sound_lab_-_Lost_by_Snowflake_Vivid_Sound_Lab_Remix.mp3',
        length: "3:34",
        startTime: '2105',
        currTime: '0:00'
    }];

    $scope.currentItem = $scope.music[currentIndex];
    $scope.currentItem.sliderVal = 0;

    $scope.listviewOptions = {
        swipe: false,
        enhance: true,
        theme: $scope.theme,
        altRow: true,
        onItemTap: function (event, inst) {
            $scope.$apply(function () {
                if (event.index !== currentIndex) {
                    changeTrack(event.index);
                    currentIndex = event.index;
                } else {
                    $scope.currentItem.status = 'play';
                }

                $timeout(function () {
                    $scope.showPlayer = true;
                    $scope.started = false;
                    //$location.search('player', 'full');
                    //window.location.hash = 'modal=Player';
                    hash.pushState({ modal: 'Player' });
                }, 100);

            });
        }
    };

    $scope.widgetOptions = {
        display: 'center',
        buttons: [],
        context: MS.context1,
        theme: $scope.theme,
        animate: 'pop'
    };

    $scope.onBackPress = function () {
        //$location.search('player', 'list');
        window.history.back();
    };

    $scope.onPictureTap = function () {
        $scope.showPlayer = true;
        //$location.search('modal', 'Player');
        hash.pushState({ modal: 'Player' });
        //window.location.hash = 'modal=Player';
        //$location.search('player', 'full');
    };

    $scope.notify = function (text) {
        $scope.message = text;

        clearTimeout(messageTimer);

        message.show();

        if (message.hasClass('music-message-v')) {
            message.removeClass('music-message-v');
            messageTimer = setTimeout(function () {
                message.addClass('music-message-v');
            }, 200);
        } else {
            message.addClass('music-message-v');
        }

        messageTimer = setTimeout(function () {
            message.removeClass('music-message-v');
            messageTimer = setTimeout(function () {
                message.hide();
            }, 200);
        }, 2000);
    };

    $scope.sliderChange = function (percent) {
        audio.currentTime = audio.duration ? percent * audio.duration / 100 : 0;
    };

    $scope.toggleShuffle = function () {
        $scope.shuffle = !$scope.shuffle;
        $scope.notify('Shuffle ' + ($scope.shuffle ? 'on' : 'off'));
    };

    $scope.toggleLike = function () {
        $scope.currentItem.like = !$scope.currentItem.like;
        $scope.notify('Music ' + ($scope.currentItem.like ? 'liked' : 'disliked'));
    };

    $scope.toggleRepeat = function () {
        $scope.repeat = !$scope.repeat;
        $scope.notify('Repeat ' + ($scope.repeat ? 'on' : 'off'));
    };

    $scope.$watch('currentItem.status', function (nv) {
        switch (nv) {
            case 'play':
                if (audio.paused) {
                    audio.play();
                    $scope.showPause = true;
                } else {
                    changeTrack(currentIndex);
                }
                break;
            case 'pause':
                if (!audio.paused) {
                    audio.pause();
                    $scope.showPause = false;
                }
                break;
            case 'next':
                nextMusic();
                break;
            case 'prev':
                nextMusic(true);
                break;
            case 'stop':
                stopMusic();
                $scope.showPause = false;
                break;
        }
    });

    function stopMusic() {
        audio.load();
        $scope.currentItem.currTime = "0:00";
        $scope.currentItem.sliderVal = 0;
        $scope.hideListPlayer = true;
    }

    function nextMusic(prev) {
        $scope.currentItem.currTime = "0:00";
        $scope.currentItem.sliderVal = 0;

        if ($scope.shuffle) {
            while (randomIndex == currentIndex) {
                randomIndex = Math.floor(Math.random() * ($scope.music.length));
            }
            currentIndex = randomIndex;
        } else if (prev) {
            currentIndex = $scope.repeat && currentIndex === 0 ? $scope.music.length - 1 : Math.max(--currentIndex, 0);
        } else {
            currentIndex = $scope.repeat && currentIndex === $scope.music.length - 1 ? 0 : Math.min(++currentIndex, $scope.music.length - 1);
        }

        changeTrack(currentIndex);
    }

    function changeTrack(index) {
        $scope.started = false;
        $timeout(function () {
            $scope.currentItem.status = '';
            $scope.currentItem = $scope.music[index];
            $scope.currentItem.currTime = "0:00";
            $scope.currentItem.sliderVal = 0;
            audio.currentTime = 0;
            audio.src = $scope.baseUrl + $scope.currentItem.audio;
            audio.play();
            $scope.showPause = true;
            $scope.currentItem.status = 'play';
        }, 60);
    }

    audio = new Audio($scope.currentItem.audio);
    audio.type = "audio/mp3";
    audio.src = $scope.baseUrl + $scope.currentItem.audio;
    audio.preload = 'auto';

    // Listen for audio events
    $(audio).on('timeupdate', function () {
        var d = new Date(audio.currentTime * 1000),
            sec = d.getSeconds();

        if (!$scope.started) {
            $scope.started = true;
        }

        if ($scope.timeUpdate) {
            $scope.$apply(function () {
                $scope.currentItem.sliderVal = audio.currentTime * 100 / audio.duration;
                $scope.currentItem.currTime = d.getMinutes() + ":" + (sec < 10 ? '0' + sec : sec);
            });
        }
    }).on('ended', function () {
        if ($scope.currentItem.status != 'pause') {
            nextMusic();
        }
    });

    $scope.$watch(function () {
        return hash.getState();
    }, function (hashObj) {
        $scope.showPlayer = hashObj['modal'] === 'Player';
    }, true);

    $timeout(function () {
        // remove the slider step markup
        $('.mbsc-slider-step').remove();
    }, 500);

    $scope.changeTheme = function (theme) {
        $scope.theme = $.mobiscroll.settings.theme = theme;

        $('.music-control').trigger('mbsc-enhance');

        $timeout(function () {
            $scope.listviewOptions.theme = theme;

            $scope.widgetOptions.theme = theme;
            $scope.widgetInstance = $('.music-social-cont').mobiscroll().widget($scope.widgetOptions).mobiscroll('getInst');

            $('.music-detail-cont').mobiscroll('destroy');
            $('.music-control').mobiscroll('destroy');

            $('.music-progress').mobiscroll().slider({
                theme: $scope.theme,
                live: false
            });

            $('.music-detail-cont').mobiscroll().form({
                theme: $scope.theme
            });

            $('.music-control').mobiscroll().form({
                theme: $scope.theme
            });

            $('#musiclist').mobiscroll().listview($scope.listviewOptions);
        }, 100);
    };

}])

.directive('onSliderTouch', function () {
    return {
        restrict: 'A',
        link: function (scope, element) {
            element.on('touchstart mousedown', function () {
                scope.$apply(function () {
                    scope.timeUpdate = false;
                });
            });

            $(document).on('touchend mouseup', function () {
                scope.$apply(function () {
                    scope.timeUpdate = true;
                });
            });
        }
    };
})

.directive('noScroll', function () {
    return {
        restrict: 'A',
        link: function (scope, element) {
            element.on('touchstart touchmove', function (ev) {
                ev.preventDefault();
            });
        }
    };
})

.directive('musicPlayer', function () {
    return {
        restrict: 'E',
        templateUrl: 'music-player.html'
    };
});

$(function () {
    $('#theme').change(function () {
        var scope = angular.element('html').scope();
        scope.changeTheme($(this).val(), scope.theme);
    });
});

$(window).on('load', function () {
    $('.wrapper').removeClass('loading');
});